package empregados;

import java.util.Calendar;
import java.util.Date;

/**
 *
 * @author Carlos Eduardo
 */
public abstract class Empregado {
    private String cpf;
    private String nome;
    private String sexo;
    private Date dt_nascimento;
    private Date dt_admissao;
    private double salario_atual;
    private Date dt_desligamento;

    public abstract double limite();

    /**
     * Construtor da classe
     */
    public Empregado(String cpf, String nome, String sexo, Date dt_nascimento, Date dt_admissao, double salario_atual, Date dt_desligamento){
        this.cpf = cpf;
        this.nome = nome;
        this.sexo = sexo.toUpperCase();
        this.dt_nascimento = dt_nascimento;
        this.dt_admissao = dt_admissao;
        this.salario_atual = salario_atual;
        this.dt_desligamento = dt_desligamento;
    }
    
    /**
     * Getters e Setters
     */
    public String getCpf() { 
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getSexo() {
        return sexo;
    }

    public void setSexo(String sexo) {
        this.sexo = sexo.toUpperCase();
    }

    public Date getDt_nascimento() {
        return dt_nascimento;
    }

    public void setDt_nascimento(Date dt_nascimento) {
        this.dt_nascimento = dt_nascimento;
    }

    public Date getDt_admissao() {
        return dt_admissao;
    }

    public void setDt_admissao(Date dt_admissao) {
        this.dt_admissao = dt_admissao;
    }

    public double getSalario_atual() {
        return salario_atual;
    }

    public void setSalario_atual(double salario_atual) {
        this.salario_atual = salario_atual;
    }

    public Date getDt_desligamento() {
        return dt_desligamento;
    }

    public void setDt_desligamento(Date dt_desligamento) {
        this.dt_desligamento = dt_desligamento;
    }
    
    /**
     * Validações
     */
    
    public void validaCamposObrigatorios() throws Exception {
        if (this.cpf==null) { throw new Exception("O campo CPF é obrigatório."); }
        if (this.nome==null) { throw new Exception("O campo Nome é obrigatório."); }
        if (this.sexo==null) { throw new Exception("O campo Sexo é obrigatório."); }
        if (this.dt_nascimento==null) { throw new Exception("O campo Data de Nascimento é obrigatório."); }
        if (this.dt_admissao==null) { throw new Exception("O campo Data de Admissão é obrigatório."); }
        
        //Convertendo o campo double salario_atual para Double, para verificar se é nulo.
        Double salario = new Double(this.salario_atual);
        if (salario==null) { throw new Exception("O campo Salário Atual é obrigatório."); }
    }
    
    public boolean validaCPF() throws Exception {  
        if (this.cpf.equals("")) {  
            return false; 
        }  
        int d1, d2;  
        int digito1, digito2, resto;  
        int digitoCPF;  
        String nDigResult;  
  
        d1 = d2 = 0;  
        digito1 = digito2 = resto = 0;  
  
        try {    
            for (int nCount = 1; nCount < this.cpf.length() - 1; nCount++) {  
                digitoCPF = Integer.valueOf(this.cpf.substring(nCount - 1, nCount)).intValue();  

                //multiplique a ultima casa por 2 a seguinte por 3 a seguinte por 4 e assim por diante.  
                d1 = d1 + (11 - nCount) * digitoCPF;  

                //para o segundo digito repita o procedimento incluindo o primeiro digito calculado no passo anterior.  
                d2 = d2 + (12 - nCount) * digitoCPF;  
            }  

            //Primeiro resto da divisão por 11.  
            resto = (d1 % 11);  

            //Se o resultado for 0 ou 1 o digito é 0 caso contrário o digito é 11 menos o resultado anterior.  
            if (resto < 2) {  
                digito1 = 0;  
            } else {  
                digito1 = 11 - resto;  
            }  

            d2 += 2 * digito1;  

            //Segundo resto da divisão por 11.  
            resto = (d2 % 11);  

            //Se o resultado for 0 ou 1 o digito é 0 caso contrário o digito é 11 menos o resultado anterior.  
            if (resto < 2) {  
                digito2 = 0;  
            } else {  
                digito2 = 11 - resto;  
            }  

            //Digito verificador do CPF que está sendo validado.  
            String nDigVerific = this.cpf.substring(this.cpf.length() - 2, this.cpf.length());  

            //Concatenando o primeiro resto com o segundo.  
            nDigResult = String.valueOf(digito1) + String.valueOf(digito2);  

            //comparar o digito verificador do cpf com o primeiro resto + o segundo resto.  
            return nDigVerific.equals(nDigResult); 
        } catch (Exception e) {
            return false;
        }
        
    }
    
   
       public void validaCPFexistente() throws Exception {
        
       }
       
       public void validaNome() throws Exception {
           if (this.nome.length()>100) { throw new Exception("O tamanho máximo do campo NOME é de 100 caracteres."); }
       }
       
       public void validaSexo() throws Exception {
           if ((!"M".equals(this.sexo)) && (!"F".equals(this.sexo))) { throw new Exception("Sexo inválido. Os valores válidos são M ou F."); }
       }
       
       public void validaDatas() throws Exception {
           if(this.dt_nascimento.after(new Date())) { throw new Exception("A data de nascimento não pode ser posterior à data atual."); }
           if(this.dt_admissao.after(new Date())) { throw new Exception("A data de admissão não pode ser posterior à data atual."); }
           if(this.dt_desligamento.after(new Date())) { throw new Exception("A data de desligamento não pode ser posterior à data atual."); }
       }
       
       public void validaDataAdmissao() throws Exception {
           if(this.dt_admissao.before(this.dt_nascimento)) { throw new Exception("A data de admissão deve ser posterior à data de nascimento."); }
       }
       
       public void validaIdadeMinimaAdmissao() throws Exception {
           Calendar dataNascimento = Calendar.getInstance();  
           dataNascimento.setTime(this.dt_nascimento);  
           Calendar dataAtual = Calendar.getInstance();  

           Integer diferencaMes = dataAtual.get(Calendar.MONTH) - dataNascimento.get(Calendar.MONTH);  
           Integer diferencaDia = dataAtual.get(Calendar.DAY_OF_MONTH) - dataNascimento.get(Calendar.DAY_OF_MONTH);  
           Integer idade = (dataAtual.get(Calendar.YEAR) - dataNascimento.get(Calendar.YEAR));  

           if(diferencaMes < 0  || (diferencaMes == 0 && diferencaDia < 0)) {  
               idade--;
           }  
           
           if(idade<=18) { throw new Exception("Não é permitido ter funcionários com menos de 18 anos."); }
       }
       
       public void validaSalarioAtual() throws Exception {
           if (this.salario_atual < 500 || this.salario_atual > 100000) { throw new Exception("Valor de salário não permitido. Ele deve ser maior ou igual a 500 e menor ou igual a 100.000."); }
       }
       
       public void validaDataDesligamento() throws Exception {
           if (this.dt_desligamento.before(this.dt_admissao)) { throw new Exception("A data de desligamento deve ser posterior à data de admissão."); }
       }
       
}
